﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ITM495.OOExamples.Core
{
    /// <summary>
    /// The controller factory is responsible for creating an IController instance 
    /// </summary>
    public class ControllerFactory
    {
        /// <summary>
        /// This method returns an controller instance given the name of a controller.
        /// 
        /// If not controller with the given name is found then the HelpController is returned
        /// </summary>
        /// <param name="name">The name of the controller. Could be Shape or ShapeController.</param>
        /// <remarks>There is a little black magic here. IF IT SEEMS WEIRD LEAVE IT ALONE. We will refactor it later</remarks>
        public IController GetController(string name, Options options)
        {
            //
            // Allow the controller name to be 'Shape' or 'ShapeController'
            //
            var controllerName = ! (name.ToLower().EndsWith("controller") )? name.ToLower() + "controller" : name.ToLower();

            //
            // We are going to grab all the types in the current assembly 
            //
            var types = Assembly.GetExecutingAssembly().GetTypes();

            //
            // Then we are going to look for a type that matches our controller name
            // and implements the IController interface
            //
            foreach(var t in types)
            {
                if(t.Name.ToLower() == controllerName && typeof(IController).IsAssignableFrom(t))
                {
                    //
                    //This line uses reflection to creats a new instance of the given type
                    // NOTE: This way of creating objects requires that they have a parameterless constructor
                    //       We will fix this shortcoming when we introduce IoC containers 
                    //
                    var controller =  Activator.CreateInstance(t) as IController;
                    return controller;
                }
            }

            //
            // We didn't find a controller by that name that implements IController so we'll just send back the 
            // HelpController and let the client try again
            //
            return new HelpController();
        }
    }
}
